package com.hello.gateway.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 网关日志工具类
 * 
 * @author hello
 */
public class GatewayLogUtils {
    private static final Logger log = LoggerFactory.getLogger(GatewayLogUtils.class);
    
    /**
     * 记录路由请求开始日志
     *
     * @param exchange 服务器Web交换
     * @param routeId 路由ID
     */
    public static void logRouteStart(ServerWebExchange exchange, String routeId) {
        ServerHttpRequest request = exchange.getRequest();
        String requestPath = request.getURI().getPath();
        String requestMethod = request.getMethod().name();
        String requestIp = request.getRemoteAddress().getAddress().getHostAddress();
        
        log.info("┏━━━━━━━━━━━━━━━ 网关路由请求开始 ━━━━━━━━━━━━━━━┓");
        log.info("┃ 路由ID: {}", routeId);
        log.info("┃ 请求路径: {}", requestPath);
        log.info("┃ 请求方法: {}", requestMethod);
        log.info("┃ 客户端IP: {}", requestIp);
        log.info("┃ 请求参数: {}", getQueryParams(request));
        log.info("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
        
        // 增加详细的请求头记录
        logRequestHeaders(request);
    }
    
    /**
     * 记录路由请求完成日志
     *
     * @param exchange 服务器Web交换
     * @param routeId 路由ID
     * @param executionTime 执行时间(ms)
     */
    public static void logRouteComplete(ServerWebExchange exchange, String routeId, long executionTime) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        
        log.info("┏━━━━━━━━━━━━━━━ 网关路由请求完成 ━━━━━━━━━━━━━━━┓");
        log.info("┃ 路由ID: {}", routeId);
        log.info("┃ 请求路径: {}", request.getURI().getPath());
        log.info("┃ 响应状态: {}", response.getStatusCode());
        log.info("┃ 执行时间: {}ms", executionTime);
        log.info("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
        
        // 增加详细的响应头记录
        logResponseHeaders(response);
    }
    
    /**
     * 记录过滤器执行日志
     *
     * @param filterName 过滤器名称
     * @param requestPath 请求路径
     * @param result 执行结果
     */
    public static void logFilterExecution(String filterName, String requestPath, boolean result) {
        log.info("┏━━━━━━━━━━━━━━━ 网关过滤器执行 ━━━━━━━━━━━━━━━━┓");
        log.info("┃ 过滤器: {}", filterName);
        log.info("┃ 请求路径: {}", requestPath);
        log.info("┃ 执行结果: {}", result ? "通过" : "拦截");
        log.info("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
    }
    
    /**
     * 记录异常日志
     *
     * @param routeId 路由ID
     * @param requestPath 请求路径
     * @param e 异常
     */
    public static void logRouteError(String routeId, String requestPath, Throwable e) {
        log.error("┏━━━━━━━━━━━━━━━ 网关路由异常 ━━━━━━━━━━━━━━━━━┓");
        log.error("┃ 路由ID: {}", routeId);
        log.error("┃ 请求路径: {}", requestPath);
        log.error("┃ 异常类型: {}", e.getClass().getName());
        log.error("┃ 异常消息: {}", e.getMessage());
        log.error("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
    }

    /**
     * 记录详细的请求头信息
     *
     * @param request HTTP请求
     */
    public static void logRequestHeaders(ServerHttpRequest request) {
        HttpHeaders headers = request.getHeaders();
        log.debug("┏━━━━━━━━━━━━━━━ 请求头详细信息 ━━━━━━━━━━━━━━━┓");
        log.debug("┃ 请求URI: {}", request.getURI());
        log.debug("┃ 请求方法: {}", request.getMethod());
        headers.forEach((name, values) -> {
            log.debug("┃ 请求头 [{}]: {}", name, String.join(", ", values));
        });
        log.debug("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
    }

    /**
     * 记录详细的响应头信息
     *
     * @param response HTTP响应
     */
    public static void logResponseHeaders(ServerHttpResponse response) {
        HttpHeaders headers = response.getHeaders();
        log.debug("┏━━━━━━━━━━━━━━━ 响应头详细信息 ━━━━━━━━━━━━━━━┓");
        log.debug("┃ 响应状态: {}", response.getStatusCode());
        headers.forEach((name, values) -> {
            log.debug("┃ 响应头 [{}]: {}", name, String.join(", ", values));
        });
        log.debug("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
    }

    /**
     * 记录路由转发详情
     *
     * @param routeId 路由ID
     * @param sourceUrl 源请求URL
     * @param targetUrl 目标请求URL
     * @param headers 转发的请求头
     */
    public static void logRouteForward(String routeId, String sourceUrl, String targetUrl, HttpHeaders headers) {
        log.debug("┏━━━━━━━━━━━━━━━ 路由转发详情 ━━━━━━━━━━━━━━━━━┓");
        log.debug("┃ 路由ID: {}", routeId);
        log.debug("┃ 源请求: {}", sourceUrl);
        log.debug("┃ 目标URL: {}", targetUrl);
        log.debug("┃ 转发请求头:");
        headers.forEach((name, values) -> {
            log.debug("┃    [{}]: {}", name, String.join(", ", values));
        });
        log.debug("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
    }
    
    /**
     * 获取请求参数
     *
     * @param request 请求
     * @return 请求参数字符串
     */
    private static String getQueryParams(ServerHttpRequest request) {
        List<String> paramList = new ArrayList<>();
        Map<String, String> queryParams = request.getQueryParams().toSingleValueMap();
        
        if (!queryParams.isEmpty()) {
            for (Map.Entry<String, String> entry : queryParams.entrySet()) {
                paramList.add(entry.getKey() + "=" + entry.getValue());
            }
            return String.join("&", paramList);
        }
        
        return "无参数";
    }
} 